﻿using System.Threading;

namespace Portal.Data.Queue
{
    public class IncreaseBookView
    {
        private class Temp
        {
            public Temp(int bookId)
            {
                BookId = bookId;
            }

            public int BookId { get; set; }
        }

        private System.Collections.Queue A = new System.Collections.Queue();
        private System.Collections.Queue B = new System.Collections.Queue();
        private System.Collections.Queue Cur;
        private static IncreaseBookView Singleton = null;
        private AutoResetEvent DataReadyFlag = new AutoResetEvent(false);
        private Mutex QueueAccessFlag = new Mutex();
        private Thread ThreadSending = new Thread(new ParameterizedThreadStart(SendWorker));
        private IncreaseBookView()
        {
            ThreadSending.Priority = ThreadPriority.Lowest;
            Cur = A;
        }
        public static void IncrView(int bookId)
        {
            if (Singleton == null)
            {
                Singleton = new IncreaseBookView();
                Singleton.ThreadSending.Start();
            }
            Singleton.PushMessage(new Temp(bookId));
        }
        private void PushMessage(Temp msg)
        {
            QueueAccessFlag.WaitOne();
            Cur.Enqueue(msg);
            DataReadyFlag.Set();
            QueueAccessFlag.ReleaseMutex();
        }
        private static void SendWorker(object obj)
        {
            while (true)
            {               
                Singleton.DataReadyFlag.WaitOne();
                Singleton.QueueAccessFlag.WaitOne();
                Singleton.DataReadyFlag.Reset();
                
                //swap the 2 buffer
                System.Collections.Queue tmp = Singleton.Cur;
                if (Singleton.Cur == Singleton.A)
                    Singleton.Cur = Singleton.B;
                else Singleton.Cur = Singleton.A;
                Singleton.QueueAccessFlag.ReleaseMutex();

                //delay atleast MIN seconds to process each queue 4 ensure DataSync is Successfull
                Thread.Sleep(1000);

                while (tmp.Count > 0)
                {                    
                    var row = (Temp)tmp.Dequeue();
                    Entity.Book.IncreateView(row.BookId);
                    Security.SecurityProvider.Instance.IncreaseVisit(row.BookId);                    
                }
            }
        }
    }
}